package com.msb.tank;

import com.msb.tank.constant.Dir;
import com.msb.tank.constant.Group;

import java.awt.*;
import java.util.Random;
import java.util.UUID;

/**
 * @Description :
 * @Version : V1.0.0
 * @Date : 2022/9/21 20:45
 */
public class Tank {
    /**
     * tank 速度
     */
    private static final int SPEED = 2;

    /**
     * tank的宽度
     */
    public static int WIDTH = ResourceMgr.goodTankU.getWidth();

    /**
     * tank的高度
     */
    public static int HEIGHT = ResourceMgr.goodTankU.getHeight();

    private UUID id = UUID.randomUUID();

    /**
     * tank所在矩形区域
     */
    Rectangle rect = new Rectangle();

    private Random random = new Random();

    /**
     * tank的位置
     */
    private volatile int x, y;

    private volatile Dir dir = Dir.DOWN;

    private boolean moving = false;

    private TankFrame tf = null;

    private boolean living = true;

    public boolean isLiving() {
        return living;
    }

    public int getX() {
        return x;
    }

    public int getY() {
        return y;
    }

    public UUID getId() {
        return id;
    }

    public void setLiving(boolean living) {
        this.living = living;
    }

    private Group group = Group.BAD;

    public Tank(int x, int y, Dir dir, Group group, TankFrame tf) {
        this.x = x;
        this.y = y;
        this.dir = dir;
        this.group = group;
        this.tf = tf;

        rect.x = x;
        rect.y = y;
        rect.width = WIDTH;
        rect.height = HEIGHT;
    }

    /**
     * 边界检查
     */
    private void boundsCheck() {
        if (this.x < 2) {
            x = 2;
        }
        if (this.y < 28) {
            y = 28;
        }
        if (this.x > TankFrame.GAME_WIDTH - Tank.WIDTH - 2) {
            x = TankFrame.GAME_WIDTH - Tank.WIDTH - 2;
        }
        if (this.y > TankFrame.GAME_HEIGHT - Tank.HEIGHT - 2) {
            y = TankFrame.GAME_HEIGHT - Tank.HEIGHT - 2;
        }
    }

    public boolean isBound() {
        if (this.x < 2 || this.y < 28
                || this.x > TankFrame.GAME_WIDTH - Tank.WIDTH - 2
                || this.y > TankFrame.GAME_HEIGHT - Tank.HEIGHT - 2) {
            return true;
        }
        return false;
    }

    /**
     * tank阵亡
     */
    public void die() {
        this.living = false;
        // 设置阵亡位置
        int eX = this.getX() + Tank.WIDTH / 2 - Explode.WIDTH / 2;
        int eY = this.getY() + Tank.HEIGHT / 2 - Explode.HEIGHT / 2;
        TankFrame.INSTANCE.explodes.add(new Explode(eX, eY));
    }

    public void fire() {
        // 设置开火的位置
        int bX = this.x + Tank.WIDTH / 2 - Bullet.WIDTH / 2;
        int bY = this.getY() + Tank.HEIGHT / 2 - Bullet.HEIGHT / 2;
        Bullet b = new Bullet(this.id, bX, bY, this.dir, this.group, this.tf);
        tf.bullets.add(b);
        // 发送开火信息 TODO
        // Client.INSTANCE.send(new BulletNewMsg(b));
        if (this.group == Group.GOOD) {
            new Thread(() -> new Audio("audio/tank_fire.wav").play()).start();
        }
    }

    public boolean isMoving() {
        return moving;
    }

    private void move() {
        if (!living) return;

        if (!moving) return;

        //save the oldDir for TankDirChangedMsg
        //oldDir = dir;

        switch (dir) {
            case LEFT:
                x -= SPEED;
                break;
            case UP:
                y -= SPEED;
                break;
            case RIGHT:
                x += SPEED;
                break;
            case DOWN:
                y += SPEED;
                break;
        }

        if (this.group == Group.BAD && random.nextInt(100) > 95)
            this.fire();
//
//        if(this.group == Group.BAD && random.nextInt(100) > 95)
//            randomDir();
        if (this.group == Group.BAD) {

        }
        boundsCheck();
        //update rect
        rect.x = this.x;
        rect.y = this.y;
    }

    public void paint(Graphics g) {
        //uuid on head
        Color c = g.getColor();
        g.setColor(Color.YELLOW);
//        g.drawString(id.toString(), this.x, this.y - 20);
//        g.drawString("live=" + living, x, y-10);
        g.setColor(c);

        //draw a rect if dead!
        if (!living) {
            moving = false;
            Color cc = g.getColor();
            g.setColor(Color.black);
            g.drawRect(x, y, WIDTH, HEIGHT);
            g.setColor(cc);
            return;
        }
        switch (dir) {
            case LEFT:
                g.drawImage(this.group == Group.GOOD ? ResourceMgr.goodTankL : ResourceMgr.badTankL, x, y, null);
                break;
            case UP:
                g.drawImage(this.group == Group.GOOD ? ResourceMgr.goodTankU : ResourceMgr.badTankU, x, y, null);
                break;
            case RIGHT:
                g.drawImage(this.group == Group.GOOD ? ResourceMgr.goodTankR : ResourceMgr.badTankR, x, y, null);
                break;
            case DOWN:
                g.drawImage(this.group == Group.GOOD ? ResourceMgr.goodTankD : ResourceMgr.badTankD, x, y, null);
                break;
        }
        move();
    }

    private void randomDir() {

        this.dir = Dir.values()[random.nextInt(4)];

    }

    public void setDir(Dir dir) {
        this.dir = dir;
    }


    public void setGroup(Group group) {
        this.group = group;
    }

    public void setId(UUID id) {
        this.id = id;
    }

    public void setMoving(boolean moving) {
        this.moving = moving;
    }

    public Dir getDir() {
        return dir;
    }
}
